<?php
define('SYS_PATH',   dirname(__FILE__).DIRECTORY_SEPARATOR);
define('ROOT',       dirname(SYS_PATH).DIRECTORY_SEPARATOR);
define('DATA_PATH',  ROOT.'data'.DIRECTORY_SEPARATOR);
define('THEME_PATH', ROOT.'theme'.DIRECTORY_SEPARATOR);

define('IS_DBUG', true);
if (IS_DBUG) {
	error_reporting(E_ALL ^ E_NOTICE);
} else {
	error_reporting(0);
}

require SYS_PATH.'Lib/Functions.php';

class JBlog {
	const VERSION = '2.0'; //版本号
	const RELEASE = '20120501'; //发布日期
	const CHARSET = 'UTF-8'; //编码
	const DBUG = true; //是否调试模式
	
	private static $init = false;

	protected static $instance;
	protected $params = array(); //参数列表
	
	/**
	 * @var object 数据库对象
	 */
	protected $db;
	
	/**
	 * @var object input对象
	 */
	protected $input;
	
	/**
	 * @var object 内存缓存对象
	 */
	protected $cache;
	
	
	protected $data = array();
	
	/**
	 * @var int 当前登录的玩家ID
	 */
	public $userid = 0;
	
	/**
	 * @var object 当前登录的玩家对象
	 */
	public $user = null;
	
	
	protected function __construct() {
		self::$instance = &$this;
		$this->init();
		
	}
	
	/**
	 * 获取当前类的唯一实例
	 *
	 * @return object
	 */
	public static function getInstance() {
		if (!is_object(self::$instance)) {
			self::$instance = new self();
		}
		return self::$instance;
	}
	
	/**
	 * 初始化 
	 */
	private final function init() {
		if (!self::$init) {
			//@set_magic_quotes_runtime(0);
			function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/GMT+0');
			define('NOW', time()); //当前时间戳
			if (!is_file(DATA_PATH.'config/global.php')) {
				$this->redirect('install'); //跳转到安装文件
			}
			$this->db    = self::getDb();
			$this->cache = self::getCache();
			$this->input = Input::getInstance();
			Auth::init($this);
			self::$init = true;
		}
	}
	
	/**
	 * 获取DB对象
	 * @return object 数据库操作对象
	 */
	public static function getDb() {
		static $instance = null;
		if (null === $instance) {
			$instance = Db::factory('Mysql');
			$instance->setOptions(self::config('DB_OPTIONS'));
			$instance->setPrefix(self::config('DB_PREFIX'));
		}
		return $instance;
	}
	
	/**
	 * 获取缓存对象
	 * @return object 缓存对象
	 */
	public static function getCache() {
		static $instance = null;
		if (null === $instance) {
			if (self::config('CACHE_ENABLE')) {
				$instance = Cache::factory(self::config('CACHE_TYPE'), self::config('CACHE_OPTIONS'));
			}
		}
		return $instance;
	}
	
	/**
	 * 格式化时间
	 *
	 * @param int $timestamp 时间戳，默认为当前时间戳
	 * @param string $format 格式化时间格式
	 * @return string 返回格式化后的时间
	 */
	public static function date($timestamp = NOW, $format = '') {
		$timezone = self::config('blog.timezone');
		if ( empty($format) ) $format = self::config('blog.timeformat');
		if ( empty($format) ) $format = 'Y-m-d H:i:s'; 
		return gmdate($format, $timestamp + intval($timezone) * 3600);
	}
	
	
	/**
	 * 时间字符串转换为时间戳
	 *
	 * @param string $timestr 表示时间的字符串
	 * @return int 时间戳
	 */
	public static function str2time($timestr) {
		$timezone = self::config('blog.timezone');
		return function_exists('date_default_timezone_set') ? (strtotime($timestr) - 3600 * $timezone) : strtotime($timestr);
	}
	
	/**
	 * URL跳转
	 *
	 * @param string $url 跳转URL地址
	 * @param int $time 等待时间
	 */
	protected function redirect($url, $time = 0) {
		$msg = __("系统将在{$time}秒之后自动跳转到{$url}！");
		if (!headers_sent()) {
			header('Content-Type:text/html; charset='.self::CHARSET);
			header("HTTP/1.1 301 Moved Permanently");
			if ($time == 0) {
				header("Location: {$url}");
			} else {
				header("refresh:{$time};url={$url}");
				echo($msg);
			}
		} else {
			echo '<meta http-equiv="Content-Type" content="text/html; charset='.self::CHARSET.'"/>';
			echo '<script type="text/javascript">';
			echo 'window.location.href="'.$url.'";';
			echo '</script>';
			echo '<noscript>';
			echo '<meta http-equiv="refresh" content="'.$time.';url='.$url.'" />';
			echo '</noscript>';
			echo $msg;
		}
		exit;
	}
	
	public static function run($moduleName = '') {
		ET('start');
		spl_autoload_register(array('JBlog', 'autoload'));
		set_error_handler(array('JBlog', 'errorHandler'), ini_get('error_reporting'));
		set_exception_handler(array('JBlog', 'exceptionHandler'));
		header('Content-Type:text/html; charset='.self::CHARSET);
		$router = Router::getInstance();
		$router->setRouteMap(self::config('router.*'));
		$router->dispath();
		define('MODULE_NAME',  $moduleName);
		define('CONTROL_NAME', $router->getControl());
		define('ACTION_NAME',  $router->getAction());
		$class = CONTROL_NAME . 'Control';
		if (class_exists($class)) {
			$control = new $class();
			$method = ACTION_NAME . 'Action';
			if (method_exists($control, $method)) {
				$params = $router->getParams();
				call_user_func_array(array($control, $method), array($params));
			} else {
				throw new CoreException("method ".ACTION_NAME." not exists");
			}
		} else {
			throw new CoreException("control ".CONTROL_NAME." not exists");
		}
	}
	
	/**
	 * 错误异常处理
	 * 
	 * @param int $errno
	 * @param string $errstr
	 * @param string $errfile
	 * @param int $errline 
	 */
	public static function errorHandler($errno, $errstr, $errfile, $errline) {
		echo $errstr.' on '.$errfile.' in '.$errline.'<br />';
	}
	
	public static function exceptionHandler($e) {
		self::error($e->getMessage());
	}
	
	/**
	 * autoload方法
	 * 
	 * @param string $class 
	 */
	public static function autoload($class) {
		$class = preg_replace('/([^a-z0-9\_])/i', '', $class);
		if (is_file(SYS_PATH."Core/{$class}.php")) {
			include_once SYS_PATH."Core/{$class}.php";
		} elseif (substr($class, -7) == 'Control') {
			$filename = SYS_PATH . 'Module/'.MODULE_NAME.'/'.substr($class, 0, -7).'.php';
			if (is_file($filename)) include_once $filename;
		} elseif (is_file(SYS_PATH."Model/{$class}.php")) {
			include_once SYS_PATH . "Model/{$class}.php";
		} else {
			$filename = SYS_PATH.'Lib/'.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
			if (is_file($filename)) include_once $filename;
		}
	}
	
	/**
	 * 读取配置信息
	 *
	 * @param string $name 配置项
	 * @return mixed 配置值
	 */
	public static function config($name) {
		static $_config = null;
		if (preg_match('/[^a-z0-9_\.]/i', $name)) return false;
		if (null === $_config) {
			$_config['global'] = include DATA_PATH . 'config/global.php';
		}
		if (false === strpos($name, '.')) {
			return $_config['global'][$name];
		} else {
			$name = explode('.', $name);
			if (!array_key_exists($name[0], $_config) && is_file(DATA_PATH . 'config/'.$name[0].'.php')) {
				$_config[$name[0]] = include DATA_PATH . 'config/'.$name[0].'.php';
			}
			if ($name[1] == '*') {
				return $_config[$name[0]];
			} else {
				$ret = $_config;
				foreach ($name as $v) {
					$ret = $ret[$v];
				}
				return $ret;
			}
		}
	}
	
	/**
	 * COOKIE读写
	 * 
	 * @param string $name cookie名
	 * @param mixed $value 值
	 * @param int $expire 保留时长
	 * @return mixed 
	 */
	public static function cookie($name, $value = '', $expire = 0) {
		if ('' === $value) { //取COOKIE
			$name = md5(self::config('COOKIE_PRE').$name);
			return isset($_COOKIE[$name]) ? $_COOKIE[$name] : false;
		} else {
			$expire = $expire > 0 ? NOW + $expire : (null === $value ? (NOW - 3600) : 0);
			$s = $_SERVER['SERVER_PORT'] == 443 ? 1 : 0;
			return setcookie(md5(self::config('COOKIE_PRE').$name), $value, $expire, self::config('COOKIE_PATH'), self::config('COOKIE_DOMAIN'), $s);
		}
	}
	
	/**
	 * 抛出错误消息并终止程序执行
	 *
	 * @param mixed $message 错误消息
	 */
	public static function error($message = 'Page Not Found', $errcode = 'Error') {
		$charset = self::CHARSET;
		$blogname = self::config('blog.name');
		$version = self::VERSION;
		echo <<<EOT
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>{$errcode}</title>
	<meta http-equiv="Content-Type" content="text/html; charset=$charset"/>
	<style type="text/css" rel="stylesheet" >
	* {margin:0;padding:0;}
	body {background:#F8F8F8;font-family:'Microsoft YaHei', helvetica, Arial, Sans-Serif; color:#666; line-height:180%; font-size:14px;}
	a {color:#175796;text-decoration:none;}
	a:hover {color:red;text-decoration:none;}
	p {margin:5px 0;}
	h1 {background:#226A9A; color:#fff; font:normal 22px/120% 'Microsoft YaHei';text-shadow:rgba(50,50,50,.3) 1px 1px 3px; padding:5px;}
	.box {width:300px; margin:0 auto;margin-top:120px; border: 1px solid #dedede;-moz-border-radius: 10px;-webkit-border-radius: 10px;-khtml-border-radius: 10px;border-radius: 10px;-moz-box-shadow: #ccc 0 4px 18px;-webkit-box-shadow: #ccc 0 4px 18px;-khtml-box-shadow: #ccc 0 4px 18px;box-shadow: #ccc 0 4px 18px;padding: 15px;}
	.copyright {margin-top:20px;color:#666;background:#fbfbfb;font:11px 'Verdana';text-align:center;padding:10px 0;}
	</style>
</head>
<body>
	<div class="box">
		<h1>{$errcode}</h1>
		<p>{$message}</p>
		<p><a href="http://www.lisijie.org">&laquo; {$blogname}</a></p>
	</div>
	<p class="copyright">Powered by <a href="http://www.lisijie.org" target="_blank">JBlog {$version}</a> &copy 2008-2010, <a href="http://www.lisijie.org" target="_blank">lisijie.org</a>.</p>
</body>
</html>
EOT;
	exit;
	}
}
?>